package org.spring.springboot.config;

import lombok.extern.slf4j.Slf4j;
import org.spring.springboot.util.SpringContextUtils;
import org.spring.springboot.entity.Schedule;
import org.spring.springboot.entity.SchedulingRunnable;
import org.spring.springboot.mapper.ScheduleMapper;
import org.spring.springboot.mapper.ScheduleInstanceMapper;
import org.spring.springboot.service.CronTaskRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysJobRunner implements CommandLineRunner {

    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;

    @Autowired
    private ScheduleMapper jobMapper;

    @Override
    public void run(String... args) {
        List<Schedule> annotationJobList = MyListenerProcessor.scheduleList;
        List<Schedule> dbJobList = jobMapper.selectAll();

        Set<String> annotationCronKeys = annotationJobList.stream().map(Schedule::getCronKey).collect(Collectors.toSet());
        Set<String> dbCronKeys = dbJobList.stream().map(Schedule::getCronKey).collect(Collectors.toSet());

        ScheduleInstanceMapper scheduleInstanceMapper = SpringContextUtils.getBean(ScheduleInstanceMapper.class);

        // Step1:程序识别有，但是数据库没有的，得新增
        for (Schedule setting : annotationJobList) {
            if (!dbCronKeys.contains(setting.getCronKey())) {
                jobMapper.insertOne(setting);
            }
        }
        // Step2:数据库识别有，但是程序识别没有的，得删除
        for (Schedule setting : dbJobList) {
            if (!annotationCronKeys.contains(setting.getCronKey())) {
                jobMapper.delete(setting.getJobId());
            }
        }

        // 初始加载数据库里状态为正常的定时任务
        List<Schedule> jobList = jobMapper.selectValid();
        if (!CollectionUtils.isEmpty(jobList)) {
            for (Schedule job : jobList) {
                SchedulingRunnable task = new SchedulingRunnable(job.getBeanName()
                        , job.getMethodName()
                        , job.getCronKey()
                        , job.getJobId());
                task.setMapper(scheduleInstanceMapper);
                cronTaskRegistrar.addCronTask(task, job.getCronExpression());
            }
        }
    }
}